﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using _3D_Demo;

namespace _3D_Lab1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Camera camera;
        VertexPositionColor[] vertices;
        BasicEffect eff;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }
      //  Model model;
       // Model model;
        Building[] buiding;
        int nbuilding;
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
          //  model = Content.Load<Model>("china_monastery");
           
//            modelTransforms = new Matrix[model.Bones.Count];
//            model.CopyAbsoluteBoneTransformsTo(modelTransforms); 

            camera = new PerspectiveCamera();
            ((PerspectiveCamera)camera).InitCamera(
                new Vector3(0, 0,10),
                Vector3.Zero,
                new Vector3(0, 1, 0),
                1,
                100,
                MathHelper.PiOver4,
                this.Window.ClientBounds.Width / this.Window.ClientBounds.Height

                );
            vertices = new VertexPositionColor[6];
            vertices[0] = new VertexPositionColor(new Vector3(-1, 0, 0), Color.Red);
            vertices[1] = new VertexPositionColor(new Vector3(1, 0, 0), Color.White);
            vertices[2] = new VertexPositionColor(new Vector3(0,-1, 0), Color.Green);

            vertices[3] = new VertexPositionColor(new Vector3(0, 1, 0), Color.Pink);
            vertices[4] = new VertexPositionColor(new Vector3(0, 0,-1), Color.Yellow);
            vertices[5] = new VertexPositionColor(new Vector3(0, 0, 1), Color.Brown);
            eff = new BasicEffect(GraphicsDevice);
            nbuilding = 2;
            buiding = new Building[nbuilding];
            for(int i =0;i<nbuilding;i++)
                buiding[i] = new Building(Content, "china_monastery", 0.4f, new Vector3(i * 2, 0, 0), Matrix.CreateScale(MathHelper.PiOver2));
            //buiding[0] = new Building(Content, "china_monastery",0.4f,new Vector3();
            //buiding[1] = new Building(Content, "GalleonTreasure");
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        float t = 0;
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            for (int i = 0; i < nbuilding; i++)
                buiding[i].Update(gameTime);
            My3DModel model = buiding[0].Model;
            
            // TODO: Add your update logic here
            Vector3 position;
            //float R = 20;
            //position = new Vector3(
            //    (float)(R * Math.Sin(t)),
            //    0, (float)(R * Math.Cos(t)));
            //t += 0.01f;
            position = new Vector3(0, 0, t);
            t -=  0.1f;
            camera.CameraPosition = position;
            camera.Update(gameTime);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            //GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, 3
            //    , VertexPositionColor.VertexDeclaration);
            eff.VertexColorEnabled = true;
            eff.View = camera.View;
            eff.Projection = camera.Projection;
            eff.World = Matrix.Identity;
            //foreach (EffectPass pass in eff.CurrentTechnique.Passes)
            //{
            //    pass.Apply();
            //    GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, 2
            //    , VertexPositionColor.VertexDeclaration);
            

            //}
            for (int i = 0; i < nbuilding; i++)
                buiding[i].Draw(gameTime, GraphicsDevice,eff, camera);

            //GraphicsDevice.Clear(Color.CornflowerBlue);
            //Matrix view = Matrix.CreateLookAt(
            //      new Vector3(10, 10, 0),
            //      new Vector3(0, 0, 0),
            //      Vector3.Up);
            //Matrix projection = Matrix.CreatePerspectiveFieldOfView(
            //   MathHelper.ToRadians(45),
            //   GraphicsDevice.Viewport.AspectRatio,
            //   0.1f, 10000.0f);
            // Calculate the starting world matrix 
            //Matrix baseWorld = Matrix.CreateScale(0.4f) *
            //   Matrix.CreateRotationY(MathHelper.ToRadians(180));
            /*foreach (ModelMesh mesh in model.Meshes)
            {
                // Calculate each mesh's world matrix 
                //Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
                //    * baseWorld;
                foreach (BasicEffect eff in mesh.Effects)
                {
                    eff.EnableDefaultLighting();
                    eff.World = Matrix.Identity;
                    eff.View = camera.View;
                    eff.Projection = camera.Projection;
                    //BasicEffect e = (BasicEffect)part.Effect;
                    // Set the world, view, and projection  
                    // matrices to the effect 
                    //e.World = localWorld;
                    //e.View = view;
                    //e.Projection = projection;
                    //e.EnableDefaultLighting();
                }
                // Draw the mesh 
                mesh.Draw();
            } */
            // TODO: Add your drawing code here
            //foreach (ModelMesh mesh in model.Meshes)
            //{
            //    foreach (BasicEffect eff in mesh.Effects)
            //    {
            //        eff.EnableDefaultLighting();
            //        eff.World = Matrix.Identity;
            //        eff.View = camera.View;
            //        eff.Projection = camera.Projection;
            //    }
            //    mesh.Draw();
            //}
            base.Draw(gameTime);
        }
    }
}
